<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    // js为了节约性能，提高小鹿，设计成了单线程，但浏览器是多线程。
    // 同步：依次执行
    // 异步: 按实际执行
    // console.log(1);
    // console.log(2);
    // console.log(3);

    // js异步执行顺序问题
    function fn1 (cb) {
      setTimeout(() => {
        console.log("fn1");
        cb && cb();  // 容错
      }, 1000)
    }
    // fn1(function () {
    //   console.log(11);
    // })

    function fn2 (cb) {
      setTimeout(() => {
        console.log("fn2");
        cb && cb();  // 容错
      }, 1000)
    }

    function fn3 (cb) {
      setTimeout(() => {
        console.log("fn3");
        cb && cb();  // 容错
      }, 1000)
    }

    // fn1();
    // console.log(456);
    // fn2();
    // fn3();

    // 通过回调函数控制异步的执行顺序；
    fn1(function () {
      console.log("fn1执行完毕了");
      fn2(function () {
        console.log("fn2执行完毕了");
        fn3(function () {
          console.log("fun3执行完毕了");
        })
      })
    })
    // 出现了回调地狱：回调函数出现层层嵌套；写法不够优雅，可维护性差，代码量大了编辑器不识别容易出错

    // 可以通过ES6里的内置类Promise来改写异步的执行和调用方式，解决回调地狱
    // 回调地狱的解决方式：1.自定义事件  2.promise解决回调地狱（使用比较多）
  </script>
</body>

</html>